#include <cstring>

#include <algorithm>

#include "bs"
#include <iostream>
integer bs(uchar buf[], integer bufsize) {
// Buffer auxiliar doblado para no calcular wrap
	uchar auxbuf[2 * bufsize];
	memcpy(auxbuf, buf, bufsize);
	memcpy(auxbuf + bufsize, buf, bufsize);

// Arreglo de punteros / índices al buffer
	integer p[bufsize];
	for(integer i = 0; i < bufsize; i++) p[i] = i;

/* Blocksort proper: ordenamos filas de la pseudomatriz
 *		Ordenamos establemente desde p hasta p + bufsize, con una
 *	lambda-expression que captura auxbuf como referencia, y bufsize, y retorna
 *	como bool el resultado de comparar las rotaciones i y j de la pseudomatriz.
 *	Dichos i y j son contenido de p.
 */
	std::stable_sort(p, p + bufsize, [&auxbuf, bufsize](integer i, integer j) {
		return memcmp(auxbuf + i, auxbuf + j, bufsize) < 0;
	});

// Sacamos última columna
	for(integer i = 0; i < bufsize; i++) buf[i] = auxbuf[p[i] + bufsize - 1];

// Sacamos el índice como posición de la fila 0
	integer ret = 0;
	while(p[ret]) ret++;
	return ret;
}

void debs(uchar buf[], integer index, integer bufsize) {
// Arreglo de punteros / índices al buffer
	integer t[bufsize];
	for(integer i = 0; i < bufsize; i++) t[i] = i;

// Ordenamos establemente punteros a caracteres del buffer
	std::stable_sort(t, t + bufsize, [&buf](integer i, integer j) {
		return buf[i] < buf[j];
	});

// Recuperamos v y lo mandamos al buffer
	uchar v[bufsize];
	for(integer i = 0; i < bufsize; i++) v[i] = buf[index = t[index]];
	memcpy(buf, v, bufsize);
}

